package com.deying.httplockserver.core;

import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.AttributeKey;

public class HttpLockRequest {
	private final Logger logger = LoggerFactory.getLogger(HttpLockRequest.class);
	/**锁名*/
	String name;
	/**事务Id*/	
	String tid;
	/**获得锁后，锁定时间*/
	int lockTime;
	/**争夺锁的，等待时间*/
	int waitTime;
	/**重入次数*/
	int reenterNum;
	ChannelHandlerContext ctx;
	/**锁定定时器*/
	ScheduledFuture<?> lockTimer;
	/**等待定时器*/
	ScheduledFuture<?> waitTimer;
	/**锁定时的时间戳*/
	Long lockedTimestamp;
	/**等待时的时间戳*/
	Long waitTimestamp;
	
	boolean alive;
	Worker worker;
	
	public HttpLockRequest(ChannelHandlerContext ctx,String name,String tid, int lockTime, int waitTime) {
		super();
		this.alive =true;
		this.ctx = ctx;
		this.name = name;
		this.tid = tid;
		this.lockTime = lockTime;
		this.waitTime = waitTime;
	}
	
	/**
	 * 接受worker控制 
	 * requestList 优化速度，省的map查询了
	 */
	public void bindWorker(Worker worker,List<HttpLockRequest> requestList){
		logger.debug("request {}-{} 绑定worker管理",name,tid);
		if(requestList==null){
			requestList =  worker.getRequestMap().get(name);
		}
		this.worker = worker;
		requestList.add(this);
	}
	
	/**
	 * 关闭,并离开worker控制
	 * requestList 优化速度，省的map查询了
	 */
	public void unBindWorker(List<HttpLockRequest> requestList){
		if(alive==true){
			logger.debug("request {}-{} 脱离worker管理",name,tid);
			alive=false;
			Assert.notNull(worker, "未和worker绑定过");
			if(requestList==null){
				requestList =  worker.getRequestMap().get(name);
			}
			if(requestList!=null){
				requestList.remove(this);
			}
			stopWaitTimer();
			stopLockerTimer();
			worker=null;
		}
	}
	public void stopWaitTimer(){
		if(waitTimer!=null){
			waitTimer.cancel(false);
			waitTimer=null;
		}
	}
	public void stopLockerTimer(){
		if(lockTimer!=null){
			lockTimer.cancel(false);
			lockTimer=null;
		};
	}
	public void postUnBindWorker(){
		if(worker!=null){
			worker.postRunnable(new Runnable() {
				@Override
				public void run() {
					unBindWorker(null);
				}
			});
		}
	}
	
	
	public ChannelHandlerContext getCtx() {
		return ctx;
	}

	public void setCtx(ChannelHandlerContext ctx) {
		this.ctx = ctx;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getLockTime() {
		return lockTime;
	}
	public void setLockTime(int lockTime) {
		this.lockTime = lockTime;
	}
	public int getWaitTime() {
		return waitTime;
	}
	public void setWaitTime(int waitTime) {
		this.waitTime = waitTime;
	}

	public Long getLockedTimestamp() {
		return lockedTimestamp;
	}

	public void setLockedTimestamp(Long lockedTimestamp) {
		this.lockedTimestamp = lockedTimestamp;
	}

	public String getTid() {
		return tid;
	}

	public void setTid(String tid) {
		this.tid = tid;
	}

	public int getReenterNum() {
		return reenterNum;
	}

	public void setReenterNum(int reenterNum) {
		this.reenterNum = reenterNum;
	}

	public ScheduledFuture<?> getLockTimer() {
		return lockTimer;
	}

	public void setLockTimer(ScheduledFuture<?> lockTimer) {
		this.lockTimer = lockTimer;
	}

	public ScheduledFuture<?> getWaitTimer() {
		return waitTimer;
	}

	public void setWaitTimer(ScheduledFuture<?> waitTimer) {
		this.waitTimer = waitTimer;
	}

	public Long getWaitTimestamp() {
		return waitTimestamp;
	}

	public void setWaitTimestamp(Long waitTimestamp) {
		this.waitTimestamp = waitTimestamp;
	}

	public boolean isAlive() {
		return alive;
	}

	public void setAlive(boolean alive) {
		this.alive = alive;
	}

	public Worker getWorker() {
		return worker;
	}

	public void setWorker(Worker worker) {
		this.worker = worker;
	}



	
	
}
